package com.yxplearn.mybatisplus.dao.core;

import com.yxplearn.mybatisplus.dao.annotation.EntryMap;
import com.yxplearn.mybatisplus.dao.annotation.PropertiesMap;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

public class EntryType<T> {

    public final static Map<Class, EntryType> entryTypeMap = new HashMap<>();

    private Class<T> clazz;
    private String tableName;
    public Map<String, Property> propertiesMap = new LinkedHashMap<>();
    private String selectAllSql;
    private Property primaryKeyFiled;

    public static void initPropertiesMap(Class clazz) {
        EntryType entryType = entryTypeMap.get(clazz);
        if (entryType == null) {
            synchronized (clazz) {
                entryType = entryTypeMap.get(clazz);
                if (entryType == null) {
                    if (clazz.isAnnotationPresent(EntryMap.class)) {
                        EntryMap entryMap = (EntryMap) clazz.getAnnotation(EntryMap.class);
                        entryType = new EntryType();
                        entryType.clazz = clazz;
                        EntryType.entryTypeMap.put(clazz, entryType);
                        entryType.setTableName(entryMap.table());
                        entryType.initProperties();
                        entryType.initSql();
                    }
                }
            }
        }
    }

    private void initProperties(){
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            if (declaredField.isAnnotationPresent(PropertiesMap.class)) {
                PropertiesMap annotation = declaredField.getAnnotation(PropertiesMap.class);
                declaredField.setAccessible(true);
                Property property = new Property();
                if (annotation.primaryKey()){
                    primaryKeyFiled = property;
                }
                property.setField(declaredField);
                property.setColumnName(annotation.column());
                property.setHandler(annotation.handler());
                propertiesMap.put(annotation.column(), property);
            }
        }
    }

    private void initSql() {
        if (propertiesMap.size() > 0) {
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("select ");
            for (Map.Entry<String, Property> entry : propertiesMap.entrySet()) {
                stringBuilder.append(entry.getKey()).append(",");
            }
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            stringBuilder.append(" from ").append(tableName);
            selectAllSql = stringBuilder.toString();
        }
    }

    // 查找
    //

    private String initSelectAllSql() {
        return selectAllSql;
    }

    private String getAllPropertyNames() {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("select ");
        for (Map.Entry<String, Property> entry : propertiesMap.entrySet()) {
            stringBuilder.append(entry.getKey()).append(",");
        }
        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        return stringBuilder.toString();
    }

    public String getSelectAllSql() {
        return selectAllSql;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableName() {
        return tableName;
    }

    public Class<T> getClazz() {
        return clazz;
    }

    public Property getPrimaryKeyFiled() {
        return primaryKeyFiled;
    }
}
